package calculator;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import org.junit.Test;

public class ParserTest {

	@Test
	public void testSimpleAddition() {
		IExpression ex = Parser.parse("2+3");
		assertEquals(5.0, ex.calculate(), 0);
		
		ex = Parser.parse("2+3+4+5");
		assertEquals(14.0, ex.calculate(), 0);
	}

	@Test
	public void testSimpleSubtraction() {
		IExpression ex = Parser.parse("3-2");
		assertEquals(1.0, ex.calculate(), 0);

		ex = Parser.parse("12-6-3-2");
		assertEquals(1.0, ex.calculate(), 0);
	}

	@Test
	public void testSimpleMultiplication() {
		IExpression ex = Parser.parse("3*2");
		assertEquals(6.0, ex.calculate(), 0);

		ex = Parser.parse("1*2*3*2*1");
		assertEquals(12.0, ex.calculate(), 0);
	}

	@Test
	public void testSimpleDivision() {
		IExpression ex = Parser.parse("4/2");
		assertEquals(2.0, ex.calculate(), 0);

		ex = Parser.parse("100/5/4/2");
		assertEquals(2.5, ex.calculate(), 0);
		
		ex = Parser.parse("1 / 0");
		try
		{
			ex.calculate();
			fail("1/0");
		}
		catch (RuntimeException e){}
	}

	@Test
	public void testSimplePower() {
		IExpression ex = Parser.parse("2^2");
		assertEquals(4.0, ex.calculate(), 0);

		ex = Parser.parse("2^2^2");
		assertEquals(16.0, ex.calculate(), 0);
	}

	@Test
	public void testExpressions() {
		IExpression ex = Parser.parse("(4/2)*(6/3)");
		assertEquals(4.0, ex.calculate(), 0);

		ex = Parser.parse("-10 * (5+5)");
		assertEquals(-100, ex.calculate(), 0);

		ex = Parser.parse("-100 / (5+5)");
		assertEquals(-10, ex.calculate(), 0);

		ex = Parser.parse("1*(2*(3*2*1))");
		assertEquals(12.0, ex.calculate(), 0);

		ex = Parser.parse("1+1^1+1*1^1");
		assertEquals(3.0, ex.calculate(), 0);
	}

	
	@Test
	public void testErrorConditions() {
		IExpression ex;
		
		try
		{
			ex = Parser.parse("(1+1");
			ex.calculate();
			fail("(1+1");
		}
		catch (RuntimeException e) {}

		try
		{
			ex = Parser.parse("1+1)");
			ex.calculate();
			fail("1+1)");
		}
		catch (RuntimeException e) {}

		try
		{
			ex = Parser.parse("1+");
			ex.calculate();
			fail("1+");
		}
		catch (RuntimeException e) {}

		try
		{
			ex = Parser.parse("^2");
			ex.calculate();
			fail("^2");
		}
		catch (RuntimeException e) {}
	}

}
